package com.company.nuwa.common.utils;

import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;
import org.springframework.transaction.support.TransactionSynchronizationAdapter;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.concurrent.Executor;
import java.util.function.Supplier;

/**
 * <p>description</p >
 *
 * @author Mitchell
 * @version 1.0
 * @date 2022/09/06 20:45
 */
public class TransactionUtils {

    /**
     * 执行事物
     *
     * @param transactionManager
     * @param runnable
     */
    public static void execute(PlatformTransactionManager transactionManager, Runnable runnable) {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            runnable.run();
            transactionManager.commit(status);
        } catch (Exception e) {
            transactionManager.rollback(status);
            throw e;
        }
    }

    /**
     * 执行事物
     *
     * @param transactionManager
     * @param runnable
     */
    public static <T> T execute(PlatformTransactionManager transactionManager, Supplier<T> runnable) {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        try {
            T o = runnable.get();
            transactionManager.commit(status);
            return o;
        } catch (Exception e) {
            transactionManager.rollback(status);
            throw e;
        }
    }


    /**
     * 在事务提交后同步执行
     *
     * @param runnable
     */
    public static void afterCommitSyncExecute(Runnable runnable) {
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                @Override
                public void afterCommit() {
                    runnable.run();
                }
            });
        } else {
            runnable.run();
        }
    }

    /**
     * 在事务提交后异步执行
     *
     * @param runnable
     */
    public static void afterCommitAsyncExecute(Executor executor, Runnable runnable) {
        if (TransactionSynchronizationManager.isSynchronizationActive()) {
            TransactionSynchronizationManager.registerSynchronization(new TransactionSynchronizationAdapter() {
                @Override
                public void afterCommit() {
                    executor.execute(runnable);
                }
            });
        } else {
            executor.execute(runnable);
        }
    }

}

